package netty.test9nettySimple;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

/**
 * 一： 用户程序自定义普通任务。
 *
 * 自定义一个handler,需要继承netty 规定好的某个handler 适配器,
 */
public class ServerHandler2 extends ChannelInboundHandlerAdapter {


    /**
     * 一： 用户程序自定义普通任务。
     * 1,这个方法是读取事件的方法，这里可以读取客户端发送的消息，参数 ChannelHandlerContext 是上下文对象，
     *  里面可以拿到 pipleLine,channel,
     *  还可以得到连接的地址，参数 msg 是客户端发送的数据，当有数据读取的时候channelRead 会被触发
     */
    @Override
    public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
        //通过这个 ChannelHandlerContext 可以拿到很多东西，比如channel,pipline 等，channel 核pipleline 是相互包含

        //将msg 转成buffer,这里 ByteBuf 是netty 提供的，性能更好
        //1,普通执行 ，这里如果 channelRead 中的操作比较耗时的话（见2），
        // 我们可以异步执行（ 所谓异步执行  就是提交到该channel对应的，
        // NIOEventLoop的taskQueue 中就可以了 ）
        // 2,模拟阻塞（模拟服务端执行比较耗时的）
        commonRun2(ctx);

    }
    private void commonRun2(ChannelHandlerContext ctx) throws InterruptedException {
        Thread.sleep(10*1000);//模拟耗时操作
        ctx.writeAndFlush(Unpooled.copiedBuffer("我是服务器，你好客户端", CharsetUtil.UTF_8));
        System.out.println("go on.....");
    }

    //2,数据读取完毕，后触发方法
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //super.channelReadComplete(ctx);
        //把数据写到缓冲，然后刷新，一般来说这个地方要对发送的数据进行编码，
        ctx.writeAndFlush(Unpooled.copiedBuffer("我是服务器，读取消息完成",CharsetUtil.UTF_8));
    }

    //3,发生异常后，一般来说要关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("客户端断开连接");
        ctx.channel().close();//用 ctx.close()也行
    }


    private void commonRun1(ChannelHandlerContext ctx, ByteBuf msg) {
        System.out.println("server handler 当前线程名字 name="+Thread.currentThread().getName());
        //super.channelRead(ctx, msg);

        ByteBuf buf= msg;
        System.out.println("客户端发送的消息是："+buf.toString(CharsetUtil.UTF_8));
        System.out.println("客户端地址："+ctx.channel().remoteAddress());
    }

}
